package club.mzywucai.blog.file_system.interceptor;

import club.mzywucai.blog.file_system.pojo.domain.JsonData;
import club.mzywucai.blog.file_system.pojo.vo.UserVo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author mzy
 * @Description 自定义拦截器；拦截前端调用接口
 * @date 2018/10/31
 */
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * @Description 进入Controller方法之前
     * @author mzy
     * @time 2018-11-03
     * @see
     * @return   boolean
     * @params  [request, response, handler]
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        HttpSession session = request.getSession();
        UserVo user = (UserVo) session.getAttribute("user");
        if (null == user) {
            // IllegalStateException: getWriter() has already been called for this response
            // getWriter() has already been called for this response
            /*
             从字面意思不难得出错误原因：HttpServletResponse中的PrintWriter已经被手动调用过了。所以当servlet执行到方法结果处理逻辑时，需要将返回值输出到writer中去，这时发现PrintWriter已经被调用过。于是servlet认为这是使用混乱的逻辑错误，于是抛出错误。

            根本原因：在Controller接口方法中，既手动调用PrintWriter向客户端输出内容，又设置了方法返回值。导致servlet需要两次将结果通过PrintWriter输出到客户端，结果报错。
            ---------------------
            作者：常乐_smile
            来源：CSDN
            原文：https://blog.csdn.net/li396864285/article/details/78122296
            版权声明：本文为博主原创文章，转载请附上博文链接！
             */

            ObjectMapper mapper = new ObjectMapper();
            PrintWriter writer = response.getWriter();

            String json = mapper.writeValueAsString(JsonData.buildError("请先登录再进行操作"));
            writer.write(json);

            return false;
        }

        return true;
    }

    /**
     * @Description 调用完Controller之后，视图渲染之前
     * @author mzy
     * @time 2018-11-03
     * @see
     * @return   void
     * @params  [request, response, handler, modelAndView]
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {

        // System.out.println("loginInterceptor -> posthandle");
    }

    /**
     * @Description 整个过程完成之后，通常用于资源清理
     * @author mzy
     * @time 2018-11-03
     * @see
     * @return   void
     * @params  [request, response, handler, ex]
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

        // System.out.println("loginInterceptor -> afterCompletion");
    }
}
